package com.ray.sso;

import java.util.Date;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.ray.api.service.UcenterApiService;
import com.ray.auth.system.emun.ManagerType;
import com.ray.auth.system.emun.UserType;
import com.ray.auth.system.table.entity.App;
import com.ray.auth.system.table.entity.Organization;
import com.ray.auth.system.table.entity.User;
import com.ray.shiro.HongWebRealm;
import com.xiaoleilu.hutool.util.ObjectUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import com.zjhc.flyhong.common.function.enums.DeleteEnum;
import com.zjhc.flyhong.common.function.error.MessageHandle;
import com.zjhc.flyhong.common.function.exception.BussinessException;
import com.zjhc.flyhong.common.function.operator.LoginUser;
import com.zjhc.flyhong.common.util.Md5Util;
import com.zjhc.flyhong.common.web.Result;
import com.zjhc.flyhong.common.web.base.BaseController;
import com.zjhc.flyhong.redis.DefaultRedisService;
import com.zjhc.shiro.captcha.DreamCaptcha;
import com.zjhc.shiro.login.ShiroLogin;
import com.zjhc.web.util.ContextHolderUtils;

@Controller
@RequestMapping("/sso")
public class SsoController extends BaseController{
	private static final Logger LOGGER = Logger.getLogger(HongWebRealm.class);
	
	@Autowired
	private UcenterApiService ucenterApiService;
	@Autowired
	private DreamCaptcha dreamCaptcha;
	@Autowired
	private DefaultRedisService defaultRedisService;
	
	
	/**
	 * @param userName
	 * @param passWord
	 * @return
	 */
	@RequestMapping(value = "login" , method=RequestMethod.GET)
	public ModelAndView doLogin(HttpServletRequest rquest, HttpServletResponse respose,
			ModelAndView modelAndView) {
		
		//如果是退出跳转登录
		String 	logout = request.getParameter("logout");
		if(StrUtil.equals(logout, "logout")){
			return this.logout(rquest, respose, modelAndView);
		}
		
	    Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        String serverSessionId = session.getId().toString();
        // 判断是否已登录，如果已登录，则回跳
        String code = defaultRedisService.get(SSOCommonValue.SSO_SESSION_ID + "_" + serverSessionId);
		
		String appid = request.getParameter("appid");
		String redirectUrl = request.getParameter("redirectUrl");
	
		
		if(StrUtil.isBlank(appid)){
			LOGGER.error(String.format("[appId:%s]:[appName:%s]-未注册的系统:%s",MessageHandle.getMsgByKey("app.id"),MessageHandle.getMsgByKey("app.name"),appid));
			throw new BussinessException(1, String.format("未注册的系统:%s", appid));
		}
		
		//获取app 对应的地址
		Result<App> appResult = ucenterApiService.queryApp(appid);
		if(appResult.codeSuccess()){
			App app = appResult.getData();
			if(app == null  || StrUtil.equals(app.getIsDelete(),DeleteEnum.DELETE.getValue())){
				LOGGER.error(String.format("[appId:%s]:[appName:%s]-未注册的系统:%s",MessageHandle.getMsgByKey("app.id"),MessageHandle.getMsgByKey("app.name"),appid));
				throw new BussinessException(1, String.format("未注册的系统:%s", appid));
			}
			redirectUrl = app.getAppSsoUrl();
			if(StrUtil.isBlank(redirectUrl)){
				throw new BussinessException(appResult.getCode(), String.format("异常信息:%s", "没有对应的url"));
			}
		}else{
			throw new BussinessException(appResult.getCode(), String.format("异常信息:%s", appResult.getMsg()));
		}
		
		
		if(StrUtil.isBlank(redirectUrl)){
			redirectUrl = MessageHandle.getMsgByKey("sso_success_url");
		}
		//HttpSession session = request.getSession();
		//记录session
		redirectUrl+= "?ssoSessionId="+serverSessionId;
		//已登录不用跳转到登录页面
		if(StrUtil.isNotBlank(code)){
			  //获取登录名称
	        String loginName = (String) subject.getPrincipals().getPrimaryPrincipal();
	        //新增用户属性
	        redirectUrl+="&userName="+loginName;
	        //生成token
	        redirectUrl+="&token="+Md5Util.getMd5(MessageHandle.getMsgByKey("sso.key")+serverSessionId);
			return new ModelAndView("redirect:"+redirectUrl);
		}
		modelAndView.addObject("redirectUrl", redirectUrl);
		modelAndView.addObject("appId", appid);
		modelAndView.setViewName("login");
		return modelAndView;
	}
	
	
	/**
	 * @param userName
	 * @param passWord
	 * @return
	 */
	@RequestMapping(value = "login" , method=RequestMethod.POST)
	public ModelAndView doLogin(String userName, String passWord, String captcha,String redirectUrl,String appId,HttpServletRequest rquest, HttpServletResponse respose,
			ModelAndView modelAndView) {
		//登录URL
		StringBuffer loginUrl = request.getRequestURL();
		loginUrl.append("?appid="+appId);
		LoginUser loginUser =  ContextHolderUtils.getLoginUser();
		if(ObjectUtil.isNull(loginUser)){
			if (StrUtil.isEmpty(captcha)) {
				modelAndView.addObject("loginError", "验证码不为空");
				modelAndView.setViewName("redirect:"+loginUrl);
				return modelAndView;
		    }
			
			if (!dreamCaptcha.validate(rquest, respose, captcha)) {
				//登录失败
				modelAndView.addObject("loginError", "验证码错误");
				modelAndView.setViewName("redirect:"+loginUrl);
				return modelAndView;
		    }
			// 判断是否登录成功
			ShiroLogin login = new ShiroLogin();
			// 判断登录状态
			boolean loginStatus = login.dologin(userName,passWord);
			if(loginStatus){
				 loginUser = new LoginUser();
					// 获取用户信息
					Result<User> userResult = ucenterApiService.queryUser(userName);
					if(userResult.codeSuccess()){
						User user = userResult.getData();
						if (ObjectUtil.isNotNull(user)) {
							loginUser.setExtendUser(user);
							loginUser.setUserName(user.getUserName());
							loginUser.setLoginName(userName);
							loginUser.setUserId(user.getUserId());
							//超级管理员
							if(StrUtil.equals(user.getManagerType(), ManagerType.SUPER.getType())){
								loginUser.setSuperManager(true);
							}
							//超级管理员
							if(StrUtil.equals(user.getUserType(), UserType.MANAGER.getType())){
								loginUser.setManager(true);
							}
							
							// 获取部门信息
							Result<Organization> deptResult = ucenterApiService.queryOrgByOrgCode(user.getOrgCode());
							if(deptResult.codeSuccess()){
								Organization dept = deptResult.getData();
								if (ObjectUtil.isNotNull(dept)) {
									loginUser.setDeptCode(dept.getOrgId());
									loginUser.setDeptName(dept.getOrgName());
								}
							}else{
								//登录失败
								modelAndView.addObject("loginError", userResult.getMsg());
								modelAndView.setViewName("redirect:"+loginUrl);
								return modelAndView;
							}
							
							// 获取所属组织信息
							Result<Organization> orgResult  = ucenterApiService.queryOrgByTenantId(user.getTenantId());
							if(deptResult.codeSuccess()){
								Organization org = orgResult.getData();
								if (ObjectUtil.isNotNull(org)) {
									loginUser.setOrgCode(org.getOrgId());
									loginUser.setOrgName(org.getOrgName());
									loginUser.setTenantId(org.getTenantId());
								}
							}else{
								//登录失败
								modelAndView.addObject("loginError", userResult.getMsg());
								modelAndView.setViewName("redirect:"+loginUrl);
								return modelAndView;
							}
							
						}
					}else{
						//登录失败
						modelAndView.addObject("loginError", userResult.getMsg());
						modelAndView.setViewName("redirect:"+loginUrl);
						return modelAndView;
					}
					
			}else{
				//登录失败
				modelAndView.addObject("loginError", "用户或密码不存在");
				modelAndView.setViewName("redirect:"+loginUrl);
				return modelAndView;
			}
		}
		//用户部门删除
		if(StrUtil.isBlank(loginUser.getTenantId())){
			//登录失败
			modelAndView.addObject("loginError", "用户所属公司已注销.");
			modelAndView.setViewName("redirect:"+loginUrl);
			return modelAndView;
		}
		// 登录时间
		loginUser.setLoginTime(new Date());
		// 信息放入session
		ContextHolderUtils.setLoginUser(loginUser);
		
		if(StrUtil.isBlank(redirectUrl)){
			redirectUrl = MessageHandle.getMsgByKey("sso_success_url");
		}
	    Subject subject = SecurityUtils.getSubject();
        Session session = subject.getSession();
        String sessionId = session.getId().toString();
        //获取登录名称
        String loginName = (String) subject.getPrincipals().getPrimaryPrincipal();
       // redirectUrl+= "?ssoSessionId="+session.getId();
        //新增用户属性
        redirectUrl+="&userName="+loginName;
        //生成token
        redirectUrl+="&token="+Md5Util.getMd5(MessageHandle.getMsgByKey("sso.key")+sessionId);
		  // 默认验证帐号密码正确，创建code
        String code = UUID.randomUUID().toString();
        // 全局会话的code
        defaultRedisService.set(SSOCommonValue.SSO_SESSION_ID + "_" + sessionId, code, (int) subject.getSession().getTimeout() / 1000);
        // code校验值
        defaultRedisService.set(SSOCommonValue.SSO_SERVER_CODE + "_" + code, Md5Util.getMd5(MessageHandle.getMsgByKey("sso.key")+sessionId), (int) subject.getSession().getTimeout() / 1000);
		return new ModelAndView("redirect:"+redirectUrl);//跳转到具体页面
	}

	
	
	@RequestMapping(value = "index")
	public ModelAndView doIndex(HttpServletRequest rquest, HttpServletResponse respose, ModelAndView modelAndView) {
		LoginUser loginUser = ContextHolderUtils.getLoginUser();
		if (ObjectUtil.isNotNull(loginUser)) {
			//跳转具体路径
		}
		//登录URL
		StringBuffer loginUrl = request.getRequestURL();
		return new ModelAndView("redirect:"+loginUrl);
	}
	
	
	@RequestMapping(value = "view")
	public ModelAndView view(HttpServletRequest rquest, HttpServletResponse respose, ModelAndView modelAndView) {
		LoginUser loginUser = ContextHolderUtils.getLoginUser();
		if (ObjectUtil.isNotNull(loginUser)) {
			modelAndView.setViewName("main");
			return modelAndView;
		}
		modelAndView.setViewName("login");
		return modelAndView;
	}


	
	@RequestMapping(value = "logout")
	public ModelAndView logout(HttpServletRequest rquest, HttpServletResponse respose, ModelAndView modelAndView) {
		 Subject subject = SecurityUtils.getSubject();  
		    if (subject.isAuthenticated()) {  
		        subject.logout(); // session 会销毁，在SessionListener监听session销毁，清理权限缓存  
		    }  
			String appid = request.getParameter("appid");
		    //登录URL
			StringBuffer loginUrl = request.getRequestURL();
			loginUrl.append("?appid="+appid);
			return new ModelAndView("redirect:"+loginUrl);
	}
	
}
